package com.learn.config;

import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

/**
 * @author DJJ_F
 * @version 1.0
 * @date 2025/08/05
 * @description ch09 网关
 * 自定义全局过滤器
 */
@Component
@Slf4j
public class MyGlobalFilter implements GlobalFilter, Ordered {
    private static final String START_TIME = "startTime";

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 在整个过滤器链和异步操作中共享同一个实例
        exchange.getAttributes().put(START_TIME, System.currentTimeMillis());

        // then()：是 Mono 类型的一个方法，用于串联两个异步操作
        // Mono.fromRunnable(() -> {})：将一个无返回值的任务（Runnable） 包装成 Mono 实例
        return chain.filter(exchange)
                .then(Mono.fromRunnable(() -> {
                    Long startTime = exchange.getAttribute(START_TIME);
                    if (startTime != null) {
                        log.info("访问接口主机: " + exchange.getRequest().getURI().getHost());
                        log.info("访问接口端口: " + exchange.getRequest().getURI().getPort());
                        log.info("访问接口URL: " + exchange.getRequest().getURI().getPath());
                        log.info("访问接口URL参数: " + exchange.getRequest().getURI().getRawQuery());
                        log.info("访问接口时长: " + (System.currentTimeMillis() - startTime) + "ms");
                        log.info("我是美丽分割线: ###################################################");
                        System.out.println();
                    }
                }));
    }

    @Override
    public int getOrder() {
        // 最后一个执行
        return Ordered.LOWEST_PRECEDENCE;
    }
}
